package com.common.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public abstract class BaseDao<T> {
	private static String driverClass="oracle.jdbc.OracleDriver";
	private String url="jdbc:oracle:thin:@localhost:1521:orcl";
	private String username="scott";
	private String password="123456";
	
	static{
		try {
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	protected Connection getConnection(){
		try {
			return DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	protected void closeAll(Connection con,Statement sta,ResultSet rs){
		try {
			if(rs!=null) rs.close();
			if(sta!=null) sta.close();
			if(con!=null) con.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	protected int executeUpdate(String sql,Object[] objs){
		Connection conn=this.getConnection();
		PreparedStatement prs=null;
		try {
			prs=conn.prepareStatement(sql);
			if(objs!=null && objs.length>0){
				for(int i=0;i<objs.length;i++){
					prs.setObject(i+1, objs[i]);
				}
			}
			return prs.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			this.closeAll(conn, prs, null);
		}
		return 0;
	}
	public abstract T getEntity(ResultSet rs);
	
	protected List<T> findBySql(String sql,Object[] obj){
		Connection conn = getConnection();
		List<T> list = new ArrayList<T>();
		PreparedStatement pst = null;
		ResultSet rs = null;
		try {
			pst = conn.prepareStatement(sql);
			if(obj.length>0&&obj!=null)
				for(int i=0;i<obj.length;i++)
					pst.setObject(i+1,obj[i]);
			rs = pst.executeQuery();
			while(rs.next()){
				list.add(getEntity(rs));
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			closeAll(conn, pst, rs);
		}
		return list;
	}
	
	/**
	 * 澧炪�鍒犮�鏀瑰姛鑳�
	 * @param sql
	 * @param objs
	 * @param primaryKeys 琛ㄧず浠庡摢涓垪鏉ヨ幏鍙栨柊鐨処D鍊�
	 * @return
	 */
	protected Object executeUpdate(String sql,Object[] objs,String[] primaryKeys){
		//1銆佽幏寰楄繛鎺ュ璞�
		Connection conn=this.getConnection();
		
		//2銆佹嫾鎺ql璇彞
		PreparedStatement prs=null;
		ResultSet rs=null;
		int rows=0;
		try {
			//3銆佽幏寰楄鍙ラ泦
			if(primaryKeys!=null){
				prs=conn.prepareStatement(sql,primaryKeys);
			}else{
				prs=conn.prepareStatement(sql);
			}
			
			//3銆佽缃崰浣嶇鐨勫�
			if(objs!=null && objs.length>0){
				for(int i=0;i<objs.length;i++){
					prs.setObject(i+1, objs[i]);
				}
			}
			rows=prs.executeUpdate();
			
			
			if(primaryKeys!=null){
				//濡傛灉鏄柊澧炲姛鑳介偅涔堥渶瑕佸皢涓婚敭鑾峰彇骞惰繑鍥�
				//鑾峰彇涓婚敭
				rs=prs.getGeneratedKeys();
				if(rs.next()){
					int primaryKey=rs.getInt(1);//鑾峰彇涓婚敭鍊�
					return new Object[]{rows,primaryKey};//鏂板
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage());
		} finally{
			this.closeAll(conn, prs, null);
		}
		return rows;
	}
	
	protected int getCount(String sql,Object[] objs){
		String countSql=" select count(*) c from ("+sql+")";
		//3.1銆佽幏寰楄繛鎺ュ璞�
		Connection conn=this.getConnection();
		PreparedStatement prs=null;
		ResultSet rs=null;
		try {
			//3.2 鑾峰緱璇彞闆�
			prs=conn.prepareStatement(countSql);
			//3.2.1銆�璁剧疆鍗犱綅绗﹀弬鏁板�
			if(objs!=null && objs.length>0){
				for(int i=0;i<objs.length;i++){
					prs.setObject(i+1, objs[i]);
				}
			}
			//3.3銆佹墽琛屾煡璇�
			rs=prs.executeQuery();
			if(rs.next()){
				return rs.getInt("c");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			this.closeAll(conn, prs, rs);
		}
		return 0;
	}
	
	protected int getSum(String attrName,String sql,Object[] objs){
		String countSql=" select sum("+attrName+") a from ("+sql+")";
		Connection conn=this.getConnection();
		PreparedStatement prs=null;
		ResultSet rs=null;
		try {
			prs=conn.prepareStatement(countSql);
			if(objs!=null && objs.length>0){
				for(int i=0;i<objs.length;i++){
					prs.setObject(i+1, objs[i]);
				}
			}
			rs=prs.executeQuery();
			if(rs.next()){
				return rs.getInt("a");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			this.closeAll(conn, prs, rs);
		}
		return 0;
	}
}
